package com.ytjj.qmyx.supplychain.api.controller;

import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.QueryTrack;
import com.kuaidi100.sdk.request.QueryTrackParam;
import com.kuaidi100.sdk.request.QueryTrackReq;
import com.kuaidi100.sdk.request.SubscribeBackBodyRequest;
import com.kuaidi100.sdk.request.SubscribeBackParamRequest;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.kuaidi100.sdk.response.QueryTrackResp;
import com.kuaidi100.sdk.response.SubscribeResp;
import com.kuaidi100.sdk.utils.PropertiesReader;
import com.kuaidi100.sdk.utils.SignUtils;
import com.ytjj.qmyx.supplychain.common.api.CommonResult;
import com.ytjj.qmyx.supplychain.common.constants.QueueConstants;
import com.ytjj.qmyx.supplychain.common.constants.RedisConstants;
import com.ytjj.qmyx.supplychain.common.model.request.ExpressOrderRequest;
import com.ytjj.qmyx.supplychain.common.utils.RedisService;
import com.ytjj.qmyx.supplychain.mapper.entity.YxBankerOrder;
import com.ytjj.qmyx.supplychain.mapper.entity.YxExpressOrders;
import com.ytjj.qmyx.supplychain.mapper.entity.YxOrderException;
import com.ytjj.qmyx.supplychain.service.BankerOrderService;
import com.ytjj.qmyx.supplychain.service.ExpressOrderService;
import com.ytjj.qmyx.supplychain.service.OrderExceptionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/express")
public class ExpressController {
    @Autowired
    private ExpressOrderService expressOrderService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private OrderExceptionService orderExceptionService;
    @Autowired
    private BankerOrderService bankerOrderService;
    @Autowired
    private RedisService redisService;

    public static void main(String[] args) {
        String mapStr = "{\"param\":\"{\\\"status\\\":\\\"shutdown\\\",\\\"billstatus\\\":\\\"check\\\",\\\"message\\\":\\\"\\\",\\\"lastResult\\\":{\\\"message\\\":\\\"ok\\\",\\\"nu\\\":\\\"YT6154301457873\\\",\\\"ischeck\\\":\\\"1\\\",\\\"condition\\\":\\\"F00\\\",\\\"com\\\":\\\"yuantong\\\",\\\"status\\\":\\\"200\\\",\\\"state\\\":\\\"3\\\",\\\"data\\\":[{\\\"time\\\":\\\"2021-12-06 11:02:02\\\",\\\"ftime\\\":\\\"2021-12-06 11:02:02\\\",\\\"context\\\":\\\"客户签收人: 已签收，签收人凭取货码签收。 已签收 感谢使用圆通速递，期待再次为您\n" +
                "服务 如有疑问请联系：18352576064，投诉电话：0510-86162898。疫情期间圆通每天对网点多次消毒，快递小哥每天测量体温，佩戴口罩\\\"},{\\\"time\\\":\\\"2021-12-04 14:20:01\\\",\\\"ftime\\\":\\\"2021-12-04 14:20:01\\\",\\\"context\\\":\\\"快件已暂存至紫金花园517栋2号车库 电联取件菜鸟驿站，如有疑问请联\n" +
                "系15720833837\\\"},{\\\"time\\\":\\\"2021-12-04 12:47:50\\\",\\\"ftime\\\":\\\"2021-12-04 12:47:50\\\",\\\"context\\\":\\\"【江苏省无锡市江阴市青阳】 已发出 下一站 【江苏省无锡市江阴市南闸街道紫金路公司】\\\"},{\\\"time\\\":\\\"2021-12-04 12:13:40\\\",\\\"ftime\\\":\\\"2021-12-04 12:13:40\\\",\\\"context\\\":\\\"【江\n" +
                "苏省无锡市江阴市青阳公司】 已收入\\\"},{\\\"time\\\":\\\"2021-12-04 12:06:15\\\",\\\"ftime\\\":\\\"2021-12-04 12:06:15\\\",\\\"context\\\":\\\"【江苏省无锡市江阴市青阳公司】 派件中 派件人: 刘勇飞 电话 18352576064 。 圆通快递小哥每天已测体温，请放心收寄快递 如有疑问，请联系：0510-86162898\\\"},{\\\"time\\\":\\\"2021-12-04 10:53:02\\\",\\\"ftime\\\":\\\"2021-12-04 10:53:02\\\",\\\"context\\\":\\\"【无锡转运中心】 已发出 下一站 【江苏省无锡市江阴市青阳公司】\\\"},{\\\"time\\\":\\\"2021-12-04 10:42:48\\\",\\\"ftime\\\":\\\"2021-12-04 10:42:48\\\",\\\"context\\\":\\\"【无锡转运中心公司】 已打包\\\"},{\\\"time\\\":\\\"2021-12-04 10:30:56\\\",\\\"ftime\\\":\\\"2021-12-04 10:30:56\\\",\\\"context\\\":\\\"【无锡转运中心公司】 已收入\\\"},{\\\"time\\\":\\\"2021-12-04 00:08:06\\\",\\\"ftime\\\":\\\"2021-12-04 00:08:06\\\",\\\"context\\\":\\\"【临海转运中心】 已发出 下一站 【无锡转运中心公司】\\\"},{\\\"time\\\":\\\"2021-12-04 00:05:53\\\",\\\"ftime\\\":\\\"2021-12-04 00:05:53\\\",\\\"context\\\":\\\"【临海转运中心公司】 已收入\\\"},{\\\"time\\\":\\\"2021-12-03 20:00:23\\\",\\\"ftime\\\":\\\"2021-12-03 20:00:23\\\",\\\"context\\\":\\\"【浙江省温岭市东部】 已发出 下一站 【临海转运中心公司】\\\"},{\\\"time\\\":\\\"2021-12-03 19:55:10\\\",\\\"ftime\\\":\\\"2021-12-03 19:55:10\\\",\\\"context\\\":\\\"【浙江省温岭市东部公司】 已打包\\\"},{\\\"time\\\":\\\"2021-12-03 19:48:33\\\",\\\"ftime\\\":\\\"2021-12-03 19:48:33\\\",\\\"context\\\":\\\"【浙江省温岭市东部公司】 已揽收 取件人: 张锷 (13282634444)\\\"}]}}\"}";
        Map<String, Object> request = JSONObject.parseObject(mapStr, Map.class);
        System.out.println(request);
        String objectJson = request.get("param").toString();
        SubscribeBackParamRequest param = JSONObject.parseObject(objectJson, SubscribeBackParamRequest.class);
        System.out.println(param);
        String com = param.getLastResult().getCom();
        String nu = param.getLastResult().getNu();
        String status = param.getStatus();// polling:监控中，shutdown:结束(已签收)，abort:中止，updateall：重新推送
        String message = param.getMessage();
        String state = param.getLastResult().getState();
    }

    @PostMapping("/callback")
    public SubscribeResp callback(@RequestParam Map<String, String> params) {
        log.info("===快递100回调参数==={}", JSONObject.toJSONString(params));
        SubscribeBackParamRequest param = null;
        if (null != params.get("param")) {
            String objectJson = params.get("param").toString();
            param = JSONObject.parseObject(objectJson, SubscribeBackParamRequest.class);
        }
        SubscribeResp resp = new SubscribeResp();
        SubscribeResp subscribeResp = new SubscribeResp();
        subscribeResp.setResult(Boolean.TRUE);
        subscribeResp.setReturnCode("200");
        subscribeResp.setMessage("成功");
        if (null == param) {
            log.info("===当前无物流数据！{}===",params);
            return subscribeResp;
        }

        String com = param.getLastResult().getCom();
        String nu = param.getLastResult().getNu();
        // status类型有：polling:监控中，shutdown:结束(已签收)，abort:中止，updateall：重新推送
        String status = param.getStatus();
        String message = param.getMessage();
        QueryTrackResp lastResult = param.getLastResult();
        Example example = new Example(YxExpressOrders.class);
        example.createCriteria().andEqualTo("companyNo", com).andEqualTo("expressEno", nu);
        List<YxExpressOrders> expressOrders = expressOrderService.selectByExample(example);
        if (CollectionUtils.isEmpty(expressOrders)) {
            log.info("===本地不存在快递单数据===");
            subscribeResp.setResult(Boolean.FALSE);
            subscribeResp.setReturnCode("502");
            subscribeResp.setMessage("当前系统暂未记录该快递单");
            return subscribeResp;
        }
        //更新订单及异常订单
        expressOrders.forEach(e->{
            expressOrderService.handleExpressResp(lastResult,e);
        });
        return subscribeResp;
    }

    /**
     * 获取快递订单列表
     * @param request
     * @return
     */
    @PostMapping("/getExpressOrdersList")
    public CommonResult getExpressOrdersList(@RequestBody ExpressOrderRequest request){
        return CommonResult.success(expressOrderService.getExpressOrdersList(request));
    }

    /**
     * 主动更新快递信息接口
     * @param expressId
     * @return
     */
    @GetMapping("/updateExpressInfo")
    public CommonResult updateExpressInfo(@RequestParam("expressId") Integer expressId){
        YxExpressOrders expressOrders = expressOrderService.selectByPrimaryKey(expressId);
        if (null == expressOrders) {
            return CommonResult.failed("参数错误");
        }
        log.info("===需要更新的物流记录的订单号:{}", expressId);
        rabbitTemplate.convertAndSend(QueueConstants.QUERY_ORDEREXPRESS, expressId);
        return CommonResult.success();
    }

    /**
     * 标记快递为无效
     * @return
     */
    @PostMapping("/markInvalidExpress")
    public CommonResult markInvalidExpress(@RequestBody List<Integer> expressIds){
        for (Integer expressId : expressIds) {
            YxExpressOrders yxExpressOrders = new YxExpressOrders();
            yxExpressOrders.setId(expressId);
            yxExpressOrders.setInvalidFlag(1);
//            yxExpressOrders.setUpdateTime(new Date());
            expressOrderService.updateByPrimaryKeySelective(yxExpressOrders);
        }
        return CommonResult.success();
    }

    /**
     * 查看发货物流（查第三方物流信息）
     * @param tel
     * @param expressCode
     * @param expressNo
     * @return
     */
    @GetMapping("/getLogisticsInfo")
    public CommonResult getLogisticsInfo(@RequestParam String tel, @RequestParam String expressCode, @RequestParam String expressNo) {
        if (!StringUtils.isEmpty(expressCode) && !StringUtils.isEmpty(expressNo)) {
            Example example = new Example(YxExpressOrders.class);
            example.createCriteria().andEqualTo("companyNo", expressCode)
                    .andEqualTo("expressEno", expressNo)
                    .andEqualTo("type",1)
                    .andEqualTo("invalidFlag",0);
            example.orderBy("id").desc();
            List<YxExpressOrders> list = expressOrderService.selectByExample(example);
            if(expressOrderService.getExpressLockForUpdate(expressCode, expressNo)){
                if(!CollectionUtils.isEmpty(list)){
                    tel = list.get(0).getPhone();
                }
                QueryTrack queryTrack = new QueryTrack();
                QueryTrackReq queryTrackReq = new QueryTrackReq();
                QueryTrackParam queryTrackParam = new QueryTrackParam();
                queryTrackParam.setCom(expressCode);
                queryTrackParam.setNum(expressNo);
                queryTrackParam.setPhone(tel);
                queryTrackReq.setParam(queryTrackParam);
                queryTrackReq.setCustomer(PropertiesReader.get("customer"));
                queryTrackReq.setSign(SignUtils.sign(new Gson().toJson(queryTrackParam) + PropertiesReader.get("key") + PropertiesReader.get("customer")));
                QueryTrackResp resp = queryTrack.queryTrack(queryTrackReq);
                try {
                    if(!CollectionUtils.isEmpty(list)){
                        new Thread(()->{
                            expressOrderService.handleExpressResp(resp,list.get(0));
                        }).start();
                    }
                } catch (Exception e) {
                    log.error("===查询快递物流，更新异常状态出错==={}", e);
                }
                return CommonResult.success(resp.getData());
            } else {
                if(CollectionUtils.isEmpty(list)){
                    return CommonResult.success();
                }
                String expressInfo = list.get(0).getInfoText();
                List<QueryTrackData> queryTrackData = JSON.parseArray(expressInfo, QueryTrackData.class);
                return CommonResult.success(queryTrackData);
            }
        } else {
            return CommonResult.failed("收件人快递信息不全！");
        }
    }

    /**
     * 查看补单物流（查第三方物流信息）
     * @param tel
     * @param expressCode
     * @param expressNo
     * @return
     */
    @GetMapping("/getReplacementOrderInfo")
    public CommonResult getReplacementOrderInfo(@RequestParam String tel, @RequestParam String expressCode, @RequestParam String expressNo) {
        if (!StringUtils.isEmpty(expressCode) && !StringUtils.isEmpty(expressNo) && !StringUtils.isEmpty(tel)) {
            QueryTrackResp resp = expressOrderService.getExpressInfoByReplacementOrder(expressNo, expressCode, tel);
            if(null == resp){
                return CommonResult.failed("补单数据有误！");
            }else {
                return CommonResult.success(resp.getData());
            }
        } else {
            return CommonResult.failed("收件人快递信息不全！");
        }
    }

    /**
     * 批量查看发货物流（查本地数据）
     * @return
     */
    @PostMapping("/getLocalLogisticsInfo")
    public CommonResult<List<YxExpressOrders>> getLocalLogisticsInfo(@RequestBody List<YxExpressOrders> expressOrders) {
        List<YxExpressOrders> result = new ArrayList<>();
        expressOrders.forEach(e->{
            String expressCode = e.getCompanyNo();
            String expressNo = e.getExpressEno();
            if (!StringUtils.isEmpty(expressCode) && !StringUtils.isEmpty(expressNo)) {
                Example example = new Example(YxExpressOrders.class);
                example.createCriteria().andEqualTo("companyNo", expressCode)
                        .andEqualTo("expressEno", expressNo)
                        .andEqualTo("type",1);
                example.orderBy("id").desc();
                List<YxExpressOrders> list = expressOrderService.selectByExample(example);
                if (!CollectionUtils.isEmpty(list)) {
                    result.add(list.get(0));
                }
            }
        });
        return CommonResult.success(result);
    }
}
